package com.xh.bussiness.tiku.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xh.bussiness.permission.bean.dto.UserDataRuleBean;
import com.xh.bussiness.permission.service.IUserService;
import com.xh.bussiness.system.service.ICourseSystemService;
import com.xh.bussiness.tiku.bean.dto.BookVersionChapterDto;
import com.xh.bussiness.system.bean.dto.DictionaryBean;
import com.xh.bussiness.system.bean.request.DictionaryRequest;
import com.xh.bussiness.system.model.Dictionary;
import com.xh.bussiness.system.service.IDictionaryService;
import com.xh.bussiness.tiku.bean.request.BookVersionRequest;
import com.xh.bussiness.tiku.constant.BookChapterConstant;
import com.xh.bussiness.tiku.model.BookVersion;
import com.xh.bussiness.tiku.dao.BookVersionMapper;
import com.xh.bussiness.tiku.service.IBookChapterService;
import com.xh.bussiness.tiku.service.IBookVersionService;
import com.xh.core.bean.AjaxResult;
import com.xh.core.service.IElasticSearchService;
import com.xh.core.service.impl.BaseServiceImpl;
import com.xh.core.util.StringUtils;
import io.searchbox.client.JestResult;
import org.springframework.beans.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xh.core.bean.XhPage;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 教材版本 服务实现类
 * </p>
 *
 * @author daiwei
 * @since 2019-01-14
 */
@Service
public class BookVersionServiceImpl extends BaseServiceImpl<BookVersionMapper, BookVersion> implements IBookVersionService {


    public static final Logger log = LoggerFactory.getLogger(BookVersionServiceImpl.class);


    @Autowired
    private IDictionaryService dictionaryService;
    @Autowired
    IBookChapterService bookChapterService;
    @Autowired
    private ICourseSystemService courseSystemService;
    @Autowired
    private IElasticSearchService elasticSearchService;
    @Autowired
    private IUserService userService;

    @Override
    public XhPage queryBookVersionPage(XhPage page, BookVersionRequest bean) {
        QueryWrapper qw = new QueryWrapper<BookVersion>();
        //拼装条件
        qw = prepareParams(bean, qw);

        return (XhPage) this.dao.selectPage(page, qw);
    }

    @Override
    public List<BookVersion> queryBookVersion(BookVersionRequest bean) {
        QueryWrapper qw = new QueryWrapper<BookVersion>();
        if (!StringUtils.isEmpty(bean.getVersionId())) {
            qw.eq("version_id", bean.getVersionId());
        } else if (!CollectionUtils.isEmpty(bean.getBookVersionIds())) {
            qw.select("distinct version_id as id,version_name as name");
            qw.in("version_id", bean.getBookVersionIds());
        } else {
            qw.select("distinct version_id as id,version_name as name");

        }
        //拼装条件
        qw = prepareParams(bean, qw);
        qw.orderByAsc("version_id,sort_index");
        return this.dao.selectList(qw);
    }


    /**
     * 准备条件
     *
     * @param bean
     * @param qw
     */
    private QueryWrapper prepareParams(BookVersionRequest bean, QueryWrapper qw) {
        if (bean.getIds() != null && bean.getIds().length > 0) {
            qw.in("id", bean.getIds());
        }
        if (StringUtils.isNotEmpty(bean.getSubject())) {
            qw.eq("subject", bean.getSubject());
        }
        if (StringUtils.isNotEmpty(bean.getGradeId())) {
            qw.eq("grade_id", bean.getGradeId());
        }

        return qw;
    }

    @Override
    public Map<String, Object> queryVresion(BookVersionRequest bean) {
        QueryWrapper qw = new QueryWrapper<BookVersion>();
        if ("primary".equals(bean.getGradeRange())) {
            qw.lt("grade_id", 7);
        } else if ("middle".equals(bean.getGradeRange())) {
            qw.lt("grade_id", 10);
            qw.gt("grade_id", 6);
        } else {
            qw.gt("grade_id", 9);
        }
        if (StringUtils.isNotEmpty(bean.getSubject())) {
            qw.eq("subject", bean.getSubject());
        }
        qw.orderByAsc("grade_id", "term_id");
        List<BookVersion> all = this.dao.selectList(qw);
        qw.groupBy("version_id");
        List<BookVersion> versions = this.dao.selectList(qw);
        Map<String, List<BookVersion>> versionGrades = new TreeMap<>();
        versions.forEach(version -> {
            all.forEach(a -> {
                if (a.getVersionId().equals(version.getVersionId())) {
                    List<BookVersion> list = versionGrades.get(a.getVersionId()) == null ? new ArrayList<BookVersion>() : versionGrades.get(a.getVersionId());
                    list.add(a);
                    versionGrades.put(a.getVersionId(), list);
                }
            });
        });
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("versions", versions);
        result.put("versionGrades", versionGrades);
        return result;
    }

    @Override
    public boolean moveUpOrDownBookVersion(String bookVersionId, Integer moveType) {
        if (StringUtils.isEmpty(bookVersionId) || moveType == null) {
            log.error("moveUpOrDownBookVersion params error");
            return false;
        }
        BookVersion bookVersion = this.getById(bookVersionId);
        if (bookVersion == null) {
            log.error(String.format("moveUpOrDownBookVersion current node is null by id:%s", bookVersionId));
            return false;
        }
        BookVersion siblingsNode = getUpOrDownBookChapter(bookVersion.getSubject(), bookVersion.getVersionId(), bookVersion.getSortIndex(), moveType);
        if (siblingsNode != null) {
            Integer oldSortIndex = bookVersion.getSortIndex();
            bookVersion.setSortIndex(siblingsNode.getSortIndex());
            siblingsNode.setSortIndex(oldSortIndex);
            //交换排序
            this.update(bookVersion);
            this.update(siblingsNode);
        }
        // 清缓存
//        deleteCache(bookVersionId);
        bookChapterService.deleteCacheBySubjectCode(bookVersion.getSubject());
        return true;
    }

    /**
     * 获取当前节点上面或下面的一个节点
     *
     * @param subjectId
     * @param versionId
     * @param sortIndex
     * @param moveType
     * @return
     */
    private BookVersion getUpOrDownBookChapter(String subjectId, String versionId, Integer sortIndex, Integer moveType) {
        QueryWrapper<BookVersion> qw = new QueryWrapper<>();
        qw.eq("subject", subjectId);
        qw.eq("version_id", versionId);
        if (moveType.equals(1)) {
            //上移
            qw.lt("sort_index", sortIndex);
            qw.orderByDesc("sort_index");
        } else {
            qw.gt("sort_index", sortIndex);
            qw.orderByAsc("sort_index");
        }
        return this.selectFirst(qw);
    }


    @Override
    public void initBookVersionSortIndex() {
        DictionaryRequest dictionaryRequest = new DictionaryRequest();
        dictionaryRequest.setTypeCode("SUBJECT");
        List<DictionaryBean> list = dictionaryService.queryDictionary(dictionaryRequest);
        for (DictionaryBean dictionary : list) {
            List<BookVersion> bookVersions = this.dao.queryBookVersionGroupByVersion(dictionary.getCode());
            for (BookVersion bookVersion : bookVersions) {
                List<BookVersion> bookVersionList = this.dao.queryBookVersionBySubjectAndVersionId(dictionary.getCode(), bookVersion.getVersionId());
                for (int i = 0; i < bookVersionList.size(); i++) {
                    BookVersion book = bookVersionList.get(i);
                    book.setSortIndex(i + 1);
                    this.update(book);
                }
            }
        }
        // 清缓存
//        bookChapterService.deleteCacheBySubjectCode(bookVersion.getSubject());
    }

    @Override
    public void truncateTable() {
        this.dao.truncateTable();
        // 清缓存
//        deleteCache();
    }

    @Override
    public List queryVersionBookTree(BookVersionRequest bookVersionRequest) {
        String subject = bookVersionRequest.getSubject();
        String index = BookChapterConstant.BOOK_CHAPTER_TREE_INDEX_PREFIX + subject;
        String type = BookChapterConstant.BOOK_CHAPTER_TREE_TYPE_PREFIX + subject;
        // es id
        String id = subject + "-" + bookVersionRequest.getUserId();

        // 查询版本
        UserDataRuleBean userDataRuleBean = userService.userDataRules(bookVersionRequest.getUserId(), bookVersionRequest.getSubject());
        if (userDataRuleBean == null || CollectionUtils.isEmpty(userDataRuleBean.getBookVersions())) {
            log.error("user data permission is null");
            return new ArrayList<>();
        }
        String key = "bookVersions";
        // 查ES
       /* Map resultMap = elasticSearchService.getDocument(index, type, id, Map.class);
        if (resultMap != null) {
            return (List<BookVersionChapterDto>) resultMap.get(key);
        }*/
        List<BookVersionChapterDto> result = new ArrayList<>();

        List<String> versionIds = userDataRuleBean.getBookVersions().stream().map(item -> item.getId()).collect(Collectors.toList());
        List<Dictionary> dictionaries = dictionaryService.queryDicByIds(versionIds);
        for (Dictionary dictionary : dictionaries) {
            BookVersionChapterDto dto = new BookVersionChapterDto();
            dto.setId(dictionary.getId());
            dto.setName(dictionary.getName());
            bookVersionRequest.setVersionId(dictionary.getId());
            List<BookVersion> books = queryBookVersion(bookVersionRequest);
            for (int j = 0; j < books.size(); j++) {
                BookVersion book = books.get(j);
                book.setChilds(bookChapterService.queryTree(book.getId()));
            }
            if (!books.isEmpty()) {
                dto.setChilds(books);
            }
            result.add(dto);
        }

//        // 存ES
//        Map saveMap = new HashMap<>();
//        saveMap.put(key, result);
//        JestResult jestResult = elasticSearchService.addIndex(saveMap, id, index, type);
//        // 如果添加不成功
//        if (!jestResult.isSucceeded()) {
//            elasticSearchService.updateIndex(saveMap, id, index, type);
//        }
        return result;

    }

    @Override
    public List<BookVersion> queryBookVersionBySubjectCode(String subjectCode) {
        return this.dao.queryBookVersionBySubjectCode(subjectCode);
    }

    @Override
    public List<Dictionary> queryBookVersionBySubject(String subjectCode) {
        List<Dictionary> dictionaries = courseSystemService.queryDictionaryByCourseSystem(subjectCode, "TEACH_BOOK_VERSION");
        if (!CollectionUtils.isEmpty(dictionaries)) {
            for (Dictionary dictionary : dictionaries) {
                List<BookVersion> bookVersions = this.dao.queryBookVersionBySubjectAndVersionId(subjectCode, dictionary.getId());
                if (!CollectionUtils.isEmpty(bookVersions)) {
                    dictionary.setBookVersions(bookVersions);
                }
            }
        }
        return dictionaries;
    }

    /**
     * 后台章节体系 模糊查询教材版本和下面的课本
     *
     * @param subjectCode
     * @return
     */
    @Override
    public List<Dictionary> queryLikeDictionaryByCourseSystem(String subjectCode, String name) {
        List<Dictionary> dictionaries = courseSystemService.queryLikeDictionaryByCourseSystem(subjectCode, name, "TEACH_BOOK_VERSION");
        if (!CollectionUtils.isEmpty(dictionaries)) {
            for (Dictionary dictionary : dictionaries) {
                List<BookVersion> bookVersions = this.dao.queryBookVersionBySubjectAndVersionId(subjectCode, dictionary.getId());
                if (!CollectionUtils.isEmpty(bookVersions)) {
                    dictionary.setBookVersions(bookVersions);
                }
            }
        }
        return dictionaries;
    }

    @Override
    public Integer getMaxSortIndex(String subjectCode, String versionId) {
        return this.dao.getMaxSortIndex(subjectCode, versionId);
    }

    @Override
    public boolean addOrUpdateBookVersion(BookVersion bookVersion) {
        boolean result;
        if (StringUtils.isEmpty(bookVersion.getId())) {
            Integer maxSortIndex = getMaxSortIndex(bookVersion.getSubject(), bookVersion.getVersionId());
            bookVersion.setSortIndex(maxSortIndex == null ? 0 : maxSortIndex + 1);
            result = this.insert(bookVersion);
        } else if (bookVersion.getDeleted() != null && bookVersion.getDeleted() == 1) {
            // 这是为了删除缓存用的，要不 bookVersion.getSubject() 为空 null
            bookVersion = super.getById(bookVersion.getId());
            result = this.dao.deleteBookVersion(bookVersion) > 0;
        } else {
            result = this.update(bookVersion);
        }
        // 清缓存
        bookChapterService.deleteCacheBySubjectCode(bookVersion.getSubject());
        return result;
    }

    @Override
    @Transactional
    public void updateSort(List<BookVersion> bookVersions) {
        for (BookVersion bookVersion : bookVersions) {
            this.update(bookVersion);
            bookChapterService.deleteCacheBySubjectCode(bookVersion.getSubject());
        }

    }

    @Override
    public boolean delete(Serializable id) {
        BookVersion bookVersion = super.getById(id);
        boolean result = super.delete(id);
        // 清缓存
        bookChapterService.deleteCacheBySubjectCode(bookVersion.getSubject());
        return result;
    }

    @Override
    public boolean batchDelete(Serializable[] ids) {
        if (ids == null || ids.length == 0) {
            return true;
        }
        BookVersion bookVersion = super.getById(ids[0]);
        boolean result = super.batchDelete(ids);
        // 清缓存
        bookChapterService.deleteCacheBySubjectCode(bookVersion.getSubject());
        return result;
    }

    // 清缓存
//    private void deleteCache(Serializable bookVersionId) {
//        if (bookVersionId == null) {
//            return;
//        }
//        BookVersion bookVersion = getById(bookVersionId);
//        if (bookVersion == null) {
//            return;
//        }
//        String subject = bookVersion.getSubject();
//        if (subject == null) {
//            return;
//        }
//        //elasticSearchService.deleteDocument(subject, BookChapterConstant.BOOK_CHAPTER_TREE_INDEX, BookChapterConstant.BOOK_CHAPTER_TREE_TYPE);
//        elasticSearchService.deleteIndex(BookChapterConstant.BOOK_CHAPTER_TREE_INDEX, BookChapterConstant.BOOK_CHAPTER_TREE_TYPE_PREFIX + subject);
//    }

    // 清缓存
//    private void deleteCache() {
//        elasticSearchService.deleteIndex(BookChapterConstant.BOOK_CHAPTER_TREE_INDEX);
//    }
}
